package plugin

import (
	"encoding/json"
	"fmt"

	"bcb-cc-observ/pkg"
	"bcb-cc-observ/pkg/channel"
	"bcb-cc-observ/pkg/models"

	hclog "github.com/hashicorp/go-hclog"
)

// 定义插件导出的结构体
type Plugin_Impl struct {
	logger  hclog.Logger
	network *pkg.S_Network
	UserId  string
	OrgId   string
}

const cnt_pluginName string = "bcb_cc_observ"

func (s *Plugin_Impl) GetName() string {
	return cnt_pluginName
}

// 设置参数
func (s *Plugin_Impl) SetParam(configContext, peerUrl, orgId, userId string) string {
	var net *pkg.S_Network
	net, err := pkg.NewNetworkByContext(configContext, peerUrl, orgId, userId)
	if err != nil {
		return Exit(201, fmt.Sprintf("创建客户端失败, %v", err), nil)
	}

	s.network = net
	s.UserId = userId
	s.OrgId = orgId
	return Exit(200, "success", nil)
}

// 通道列表
func (s *Plugin_Impl) GetChannels() string {
	arChl, err := s.network.GetChannels()
	if err != nil {
		return Exit(201, err.Error(), nil)
	}
	return Exit(200, "success", arChl)
}

// 区块信息
func (s *Plugin_Impl) GetBlockInfo(bReq []byte) string {
	var req GetBlockInfo_Req
	var resp GetBlockInfo_Resp

	//s.logger.Info(fmt.Sprintf("GetBlockInfo entry, %v", bReq))
	err := json.Unmarshal(bReq, &req)
	if err != nil {
		s.logger.Error(fmt.Sprintf("json unmarshal fail, %v", err))
		return Exit(201, err.Error(), nil)
	}

	client, err := s.network.GetLedger(req.ChannelId, s.UserId, s.OrgId)
	if err != nil {
		s.logger.Error(fmt.Sprintf("get ledger fail, %v", err))
		return Exit(201, err.Error(), nil)
	}
	clt := pkg.NewLedger(client)

	// ----------------- 区块信息 ----------------
	blk, err := clt.GetBlockInfo(req.BlockNumber)
	if err != nil {
		s.logger.Error(fmt.Sprintf("get block fail, %v", err))
		return Exit(201, err.Error(), nil)
	}
	resp.Block = *blk

	return Exit(200, "success", resp)
}

// 区块信息
func (s *Plugin_Impl) GetSummaryInfo(bReq []byte) string {
	var req GetSummaryInfo_Req
	var resp GetSummaryInfo_Resp

	err := json.Unmarshal(bReq, &req)
	if err != nil {
		return Exit(201, fmt.Sprintf("unmarshal json fail, %v", err), nil)
	}

	client, err := s.network.GetLedger(req.ChannelId, s.UserId, s.OrgId)
	if err != nil {
		return Exit(201, fmt.Sprintf("get ledger fail, %v", err), nil)
	}
	var csi *models.F_CHL_Summary_Info

	csi, err = channel.GetSummaryInfo(client, req.ChannelId)
	if err != nil {
		return Exit(201, fmt.Sprintf("get summary fail, %v", err), nil)
	}
	resp.Info = *csi
	return Exit(200, "success", resp)
}

// 交易信息
func (s *Plugin_Impl) GetTransactionInfo(bReq []byte) string {
	var req GetTransactionInfo_Req
	var resp GetTransactionInfo_Resp

	err := json.Unmarshal(bReq, &req)
	if err != nil {
		return Exit(201, fmt.Sprintf("req unmarshal fail, %v", err), nil)
	}

	client, err := s.network.GetLedger(req.ChannelId, s.UserId, s.OrgId)
	clt := pkg.NewLedger(client)

	// 交易信息
	blk, err := clt.GetTransactionInfo(req.TxId)
	if err != nil {
		return Exit(201, fmt.Sprintf("get tx fail, %v", err), nil)
	}

	resp.Info = *blk
	return Exit(200, "success", resp)
}
